package com.jt9003.controller;

import com.jt9003.pojo.*;
import com.jt9003.service.TherapyService;
import com.jt9003.utils.RedisUtil;
import com.jt9003.utils.ShuttleBoxGetData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.*;

//诊疗开方
@RestController
public class TherapyController {

    @Autowired
    TherapyService therapyService;
    @Resource
    RedisUtil redisUtil;

    //病历表对象，存储一个患者的病例信息
    Patient_case_history pch1 = new Patient_case_history();

    //储存的中成药
    List<ShuttleBoxGetData> CTMList = new ArrayList<>();

    //储存的西药
    List<ShuttleBoxGetData> WmList = new ArrayList<>();

    //储存中药处方的集合
    List<POTCM> potcmList=new ArrayList<>();

    //储存的体检项目
    List<ShuttleBoxGetData> PEList = new ArrayList<>();

    //储存的其他收费项目
    List<ShuttleBoxGetData> oplist = new ArrayList<>();

    //储存的临床诊断信息
    List<ShuttleBoxGetData> DTList = new ArrayList<>();

    //查询挂号单信息（时间是当天，已诊治，未诊治）
    @RequestMapping("/selectRegister")
    public Map selectRegister(){
        Map<String,Object> map= new HashMap<>();
        List<Register> list;
        List<Register> list2;
        try{
            //查询已诊治的挂号单信息
            list=therapyService.selectRegister();
            System.out.println("已诊治的==========="+list.size());
            //查询未诊治的挂号单信息
            list2=therapyService.selectRegister2();
            System.out.println("未诊治的==========="+list2.size());

                map.put("result",list);
                map.put("result2",list2);
                map.put("message","查询成功");
                map.put("success",true);

        }catch(Exception e){
            e.printStackTrace();
            map.put("message","查询挂号单信息异常");
            map.put("success",false);
        }
        return map;
    }

    //根据挂号单号，查询挂号单信息
    @RequestMapping("/r_info")
    public Map selectRegister3(@RequestParam("id") String registrationNumber){

        Map<String,Object> map = new HashMap<String, Object>();
        try{
            //根据挂号单号去查询该挂号单对应的信息
            Register register = therapyService.selectRegister3(registrationNumber);
            if (register!=null){
                map.put("success",true);
                map.put("message","诊疗开方页面查询成功");
                map.put("result",register);
            }else{
                map.put("success",false);
                map.put("message","诊疗开方页面查询失败");
            }
        }catch (Exception e){
            map.put("success",false);
            map.put("message","诊疗开方页面查询程序异常");
        }
        return map;
    }

    //查询所有病症
    @RequestMapping("/selectDT")
    public Map selectDTInfo(){
        Map<String,Object> map = new HashMap<>();

        try {
            List<Disease_tcm> list = therapyService.selectDTinfo();
            if (list.size()>0){
                map.put("result",list);
                map.put("success",true);
                map.put("message","查询病症成功");
            }else{
                map.put("success",false);
                map.put("message","查询病症失败");
            }
        }catch (Exception e){
            e.printStackTrace();
            map.put("success",false);
            map.put("message","查询病症异常");
        }
        return map;
    }

    /**
     * 添加患者的病例信息
     * 保存患者病例信息，等待最终提交
     */
    @RequestMapping("/PCH")
    public int addPatient_case_history(Patient_case_history pch){
        int check = 0;  //默认值，表示保存失败
        //给全局变量赋值,用于其他方法调用
        int pid = pch.getpId();
        String pName= pch.getpName();

        //到redis中取出当前登录人的名字
        String token = pch.getToken();    //获取病例对象里的token
        User1 user1 = (User1) redisUtil.get(token);

        if (pName==null||pName==""||pid==0){
            check = 2;   //未获取到当前患者信息
        }else if(user1==null){
            check = 3;      //用户未登录
        }else{
            pch.setpDiagnosisDoctor(user1.getuName());  //将redis取出来的医生名字放到病例对象中
            pch1=pch;
            check = 1;  //保存成功
        }
        return check;
    }

    /**
     * 根据患者id添加患者的临床诊断信息
     * 保存临床诊断信息，等待最终提交
     */
    @RequestMapping(value="/addclinicalCiagnosis",method = {RequestMethod.POST})
    public Map addclinicalCiagnosis(@RequestBody List<ShuttleBoxGetData> list){
        Map<String,Object> map = new HashMap<>();

        try {
            if (DTList.size()>0){
                //清空参数之后在进行添加
                DTList.clear();
                map.put("message","临床诊断修改成功");
            }else{
                map.put("message","临床诊断添加成功");
            }
            DTList=list;
            map.put("success",true);
        }catch (Exception e){
            e.printStackTrace();
            map.put("success",false);
        }
        return map;
    }


     // 添加新病症
    @RequestMapping("/addDisease")
    public Map addDisease(@RequestParam("value") String diseaseName){
        Map<String,Object> map = new HashMap<>();
        System.out.println("拿到的病证名:==================="+diseaseName);
        try{
            if (diseaseName!=null || diseaseName!=""){
                int a = therapyService.addDisease(diseaseName);
                if (a>0){
                    map.put("success",true);
                    map.put("message","添加成功");
                }else{
                    map.put("success",false);
                    map.put("message","添加失败");
                }
            }else{
                map.put("success",false);
                map.put("message","添加失败，未接收到数据");
            }
        }catch(Exception e){
            e.printStackTrace();
            map.put("success",false);
            map.put("message","添加失败，程序异常");
        }
        return map;
    }


    /**
     *  获取药品名和id,每天每次使用次数
     * @return
     */
    @RequestMapping("/selectDrugsName")
    public Map selectDrugsName(){
        Map<String,Object> map = new HashMap<>();
        List<Drugs> list =new ArrayList();
        try{
            list= therapyService.selectDrugsName();
            if (list.size()>0){
                map.put("message","药品名称查询成功");
                map.put("success",true);
                map.put("data",list);
            }else{
                map.put("message","药品名称查询失败");
                map.put("success",false);
            }
        }catch(Exception e){
            e.printStackTrace();
            map.put("message","药品名称查询异常");
            map.put("success",false);
        }
        System.out.println("返回的药品参数:"+list.get(0).getDrName());
        return map;
    }


    /**
     * 接收中药处方传过来的信息
     * prescriptions of traditional Chinese medicine
     * 用中药处方的pojo接收中药处方的数据，将数据插入(处方和药品关系表)
     * 数据中每天每次用量和药品类型可能和数据库不一致，需要额外记录
     * 前端删除中药处方时，传tab下标参数到此，正好可以与list的下标对应
     */
    @RequestMapping("/addPOTCM")
    public Map addPOTCM(POTCM potcm, @RequestParam(value = "del",required = false) Integer del){
        Map<String,Object> map=new HashMap<>();
        int drid = potcm.getDrId(); //获取药品id
        try{
            if (drid!=0){
                //保存数据
                System.out.println("获取的药品id"+potcm.getDrId());
                System.out.println("药品id对应的类型:"+potcm.getDrType());
                potcmList.add(potcm);
                map.put("message","保存中药处方成功");
            }else if (del != 0 && del != null){
                //删除对应下标的数据
                System.out.println("获取需要删除的中药处方的下标："+del);
                potcmList.remove(del);
                map.put("message","删除中药处方成功");
                //清空集合
                potcmList.clear();
            }
        }catch(Exception e){
            e.printStackTrace();
            map.put("message","保存中药处方异常");
        }
        return map;
    }



     //查询所有中成药 Chinese traditional medicine
    @RequestMapping("/CTM")
    public Map selectCTM(){
        Map<String,Object> map = new HashMap<>();
        try{
            //查询中成药
            List<Drugs> CTMlist =therapyService.selectCTM();
            if (CTMlist.size()>0){
                map.put("message","中成药品查询成功");
                map.put("list",CTMlist);
                map.put("success",true);
            }else{
                map.put("message","中成药品查询失败,没有查询到数据");
                map.put("success",false);
            }
        }catch(Exception e){
            e.printStackTrace();
            map.put("message","中成药品查询异常");
            map.put("success",false);
        }
        return map;
    }

    /**
     * 获取中成药处方选择的中成药
     * 通过工具类中设置好的对象获取穿梭框的数组
     * 如果数据是需要修改，前端发来验证信息，请求修改
     */
    @RequestMapping(value="/getCTM",method = {RequestMethod.POST})
    public Map getCTM(@RequestBody List<ShuttleBoxGetData> list){
        Map<String,Object> map = new HashMap<>();
        try {
            if (CTMList.size()>0){
                //清空参数之后在进行添加
                CTMList.clear();
                map.put("message","中成药修改成功");
            }else{
                map.put("message","中成药添加成功");
            }
            CTMList= list;
            map.put("success",true);
        }catch (Exception e){
            e.printStackTrace();
            map.put("success",false);
        }
        return map;
    }


    //查询西药  Western medicine
    @RequestMapping("/selectWm")
    public Map selectWm(){
        Map<String,Object> map = new HashMap<>();

        try{
            List<Drugs> list = therapyService.selectWm();
            if (list.size()>0){
                map.put("success",true);
                map.put("date",list);
                map.put("message","查询西药成功");
            }else{
                map.put("success",false);
                map.put("message","查询西药失败");
            }
        }catch(Exception e){
            e.printStackTrace();
            map.put("success",false);
            map.put("message","查询西药异常");
        }
        return map;
    }


    /**
     * 接收选择的西药
     * Western medicine
     */
    @RequestMapping(value="/getWm",method = {RequestMethod.POST})
    public Map getWm(@RequestBody List<ShuttleBoxGetData> list){

        Map<String,Object> map = new HashMap<>();
        //将数据放到Drugs对象中,再将Drugs对象放到集合中
        try{
            if (WmList.size()>0){
                //清空参数之后在进行添加
                WmList.clear();
                map.put("message","西药修改成功");
            }else{
                map.put("message","西药添加成功");
            }
            WmList=list;
            map.put("success",true);
        }catch (Exception e){
            e.printStackTrace();
            map.put("success",false);
        }
        return map;
    }


    //查询所有体检项目  physical_examination
    @RequestMapping("/selectPE")
    public Map selectPE(){
        Map<String,Object> map = new HashMap<>();
        try {
            List<Physical_examination> list = therapyService.selectPE();
            if (list.size()>0){
                map.put("date",list);
                map.put("success",true);
                map.put("message","体检项目查询成功");
            }else {
                map.put("success",false);
                map.put("message","体检项目查询失败");
            }
        }catch (Exception e){
            e.printStackTrace();
            map.put("success",false);
            map.put("message","体检项目查询异常");
        }
        return map;
    }

    /**
     * 获取选择的体检项目
     */
    @RequestMapping(value="/getPE",method = {RequestMethod.POST})
    public Map getPE(@RequestBody List<ShuttleBoxGetData> list){
        Map<String,Object> map = new HashMap<>();

        try {
            if (PEList.size()>0){
                //清空参数之后在进行添加
                PEList.clear();
                map.put("message","体检项目修改成功");
            }else{
                map.put("message","体检项目添加成功");
            }
            PEList=list;
            map.put("success",true);
        }catch (Exception e){
            e.printStackTrace();
            map.put("success",false);
        }
        return map;
    }

    //查询其他费用项目
    @RequestMapping("/selectOP")
    public Map selectOP(){
        Map<String,Object> map = new HashMap<>();
        try {
            List<Other_price> list = therapyService.selectOP();
            if (list.size()>0){
                map.put("date",list);
                map.put("success",true);
                map.put("message","其他费用项目查询成功");
            }else {
                map.put("success",false);
                map.put("message","其他费用项目查询失败");
            }
        }catch (Exception e){
            e.printStackTrace();
            map.put("success",false);
            map.put("message","其他费用项目查询异常");
        }
        return map;
    }


    /**
     * 获取其他费用项目
     */
    @RequestMapping("/getOP")
    public Map getOP(@RequestBody List<ShuttleBoxGetData> list){
        Map<String,Object> map = new HashMap<>();
        //将数据放到Drugs对象中,再将Drugs对象放到集合中
        try {
            if (oplist.size()>0){
                //清空参数之后在进行添加
                oplist.clear();
                map.put("message","其他费用项目修改成功");
            }else{
                map.put("message","其他费用项目添加成功");
            }
            oplist= list;
            map.put("success",true);
        }catch (Exception e){
            e.printStackTrace();
            map.put("success",false);
        }
        return map;
    }

    /**
     * 成此次就诊
     * 诊疗开方模块完提交数据，从全局变量里获取保存的药品，进行提交到数据库
     *
     * 接收导入的医疗模板数据，院内协调方和调理方只保存id就可以
     * 根据药品查询出药品/其他费用/体检的价格，计算总价，添加到处方表的处方费用中   OK
     * 检查项目的数据提交到病历表的体格检查中，逗号分开               OK
     * 临床诊断的数据提交到病历表的临床诊断中，逗号分开               OK
     * 药品id和处方id添加到药品与处方关系表中                        OK
     * 中药处方数据插入(处方和药品关系表)                            OK
     *     //储存的体检项目
     *     List<ShuttleBoxGetData> PEList = new ArrayList<>();
     *     //储存的临床诊断信息
     *     List<ShuttleBoxGetData> DTList = new ArrayList<>();
     *     //储存的其他收费项目
     *     List<ShuttleBoxGetData> oplist = new ArrayList<>();
     *      //储存的中成药
     *     List<ShuttleBoxGetData> CTMList = new ArrayList<>();
     *     //储存的西药
     *     List<ShuttleBoxGetData> WmList = new ArrayList<>();
     *     //储存中药处方的集合
     *     List<POTCM> potcmList=new ArrayList<>();
     */
    @RequestMapping(value = "/submission",method = {RequestMethod.POST})
    @Transactional
    public Map subMission(@RequestBody(required = false) List<Template> arrayData){
        Map<String,Object> map = new HashMap<>();
        List<Integer> drugsId = new ArrayList<>(); //药品id   用于计算价格
        List<Integer> drugsId2= new ArrayList<>();  //药品id2  用于传入底层修改数据
        List<Integer> PEid = new ArrayList<>();    //体检项目id
        StringBuffer t_id = new StringBuffer();        //院内协调方和调理方的id

        try {
            //取出当前患者的id 和患者名字
             int pId=pch1.getpId();
             String preName = pch1.getpName();

             //遍历体检项目:获取id去数据库查询价格,在把项目名拼成字符串  List<ShuttleBoxGetData> PEList = new ArrayList<>();
             StringBuffer potcmName=new StringBuffer();    //体检项目名
                double PEprice =0;  //体检项目的价格
             if (PEList.size()!=0){
                for (ShuttleBoxGetData sbg:PEList){
                    potcmName.append(sbg.getTitle()+",");
                    PEid.add(sbg.getValue());
                }
                //计算体检项目价格
                 PEprice = therapyService.selectPEprice(PEid);
             }

             //遍历临床诊断的病症名  List<ShuttleBoxGetData> DTList = new ArrayList<>();
             StringBuffer dtName=new StringBuffer();
             if (DTList.size()!=0){
                for (ShuttleBoxGetData sbg2:DTList){
                    dtName.append(sbg2.getTitle()+",");
                }
             }

             //遍历其他收费项目id   List<ShuttleBoxGetData> oplist = new ArrayList<>();
            double opPrice = 0;
             if (oplist.size()!=0){
                List<Integer> op = new ArrayList<>();
                for (ShuttleBoxGetData sbg3:oplist){
                    op.add(sbg3.getValue());
                }
                //其他费用的价格
               opPrice=therapyService.selectOPprice(op);
             }

             //遍历中成药id List<ShuttleBoxGetData> CTMList = new ArrayList<>();
             if (CTMList.size()!=0){
                for (ShuttleBoxGetData sbg4:CTMList){
                    drugsId.add(sbg4.getValue());
                }
             }

            //遍历西药id  List<ShuttleBoxGetData> WmList = new ArrayList<>();
             if (WmList.size()!=0){
                for (ShuttleBoxGetData sbg5:WmList){
                    drugsId.add(sbg5.getValue());
                }
             }

            //遍历中药id  List<POTCM> potcmList=new ArrayList<>();
            StringBuffer preRemarks = new StringBuffer();   //给药房的备注
            String doctorWord ="";   //医嘱


            /*遍历导入的院内协调方和调理方数据  必须位于给drugsId2赋值之后在添加给drugsId1
            不然数据库会出现重复数据。模板的id直接存到处方表中*/
            if (arrayData!=null){
                for (int i =0;i<arrayData.size();i++){
                   String ids = arrayData.get(i).getDr_ids();
                    t_id.append(arrayData.get(i).getId()+",");

                    String[] split = ids.split(",");
                    for (int j = 0; j < split.length; j++) {
                        drugsId.add(Integer.parseInt(split[j]));
                    }

                }
            }
            /*由于后面提交处方与药品关系表时要将id放回到potcmList中，
            会在原有中药id的基础上再次添加中药id，导致中药的id重复，这里在drugsId添加中药id之前复制一份*/
            for (int i:drugsId){
                drugsId2.add(i);
            }

            if (potcmList.size()!=0){
                for (POTCM sbg6:potcmList){
                    drugsId.add(sbg6.getDrId());
                    //拿出所有给药房的备注，拼成字符串
                    preRemarks.append(sbg6.getPreRemarks()+";");
                }

                doctorWord = potcmList.get(0).getDoctor_word();
            }

 //================================计算价格=================================================
            Double totalPrice = totalPrice(drugsId,PEprice,opPrice);
 //=========================================================================================


 //================================提交患者病例数据=================================================
             pch1.setpPastIllness(dtName.toString());     //病症名
             pch1.setpExamination(potcmName.toString());     //体检名
             //获取当前登录的医生的姓名
             int a = therapyService.addPatient_case_history(pch1);  //数据插入病例表
//=============================================================================================

            if (a>0){
//================================提交处方表数据=================================================
                 //设置处方对象   需要用到这个参数对象用来获取插入数据的id值
                 Prescription prescription = getPrescroption(pId,totalPrice,preName,preRemarks,doctorWord,t_id);

                 int count =therapyService.addPrescription(prescription,pch1.getpDiagnosisDoctor());   //执行插入，插入处方表的id会返回到参数的id中
//=============================================================================================

                if(count>0){
//================================提交处方与药品关系表数据=================================================
                     int preId = prescription.getPreId(); //获取返回的处方表id
                     //将中药处方数据和药品id添加到处方与药品关系表  List<POTCM> potcmList=new ArrayList<>();
                     for(int i:drugsId2){
                         POTCM potcm =new POTCM();
                         potcm.setDrId(i);
                         potcmList.add(potcm);
                     }
                     //设置处方表id
                     for (int i=0;i<potcmList.size();i++){
                         potcmList.get(i).setPre_id(preId);
                     }
                     //处方与药品关系表插入数据
                     int pdrCount = therapyService.addpreDRelationship(potcmList);
//=============================================================================================


                    if (pdrCount== potcmList.size()){
//================================修改患者状态 传入挂号单id  p_diagnosis=8=================================================
                            int rid = pch1.getrId();
                            int updata = therapyService.updataP_diagnosis(rid);
//=============================================================================================

                        if (updata>0){
                                //调用清空的全局数据方法
                                boolean check = emptyParam();
                                if (check==true){
                                    map.put("success",true);
                                    map.put("message","提交成功");
                                }else{
                                    map.put("success",false);
                                    map.put("message","清空数据失败");
                                    throw new Exception("清空数据失败");
                                }
                            }else{
                                map.put("success",false);
                                map.put("message","挂号单诊治状态修改失败");
                            throw new Exception("挂号单诊治状态修改失败");
                            }
                        }else{
                            //药品与处方关系表插入的数据数量不正确
                            map.put("success",false);
                            map.put("message","药品与处方关系表插入的数据数量不正确");
                        throw new Exception("药品与处方关系表插入的数据数量不正确");

                    }
                    }else{
                    //处方表插入数据失败或者异常，没有获取到返回的处方表id
                    map.put("success",false);
                    map.put("message","处方表添加失败");
                    throw new Exception("处方表添加失败");
                }
                 }else{
                     //患者病例添加失败
                     map.put("success",false);
                     map.put("message","患者病例添加失败");
                throw new Exception("患者病例添加失败");
            }

        }catch (Exception e){
            e.printStackTrace();
            //回滚
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            map.put("success",false);
            map.put("message","最终提交程序异常,程序回滚");
        }
        return map;
    }

    //计算药品、体检的总价、其他收费项目
    public Double totalPrice(List<Integer> drugsId,Double PEprice,Double opPrice){
        double drugsPrice =0;
        if (drugsId.size()>0){
            //查询药品总价
            drugsPrice = therapyService.selectTotalPrice(drugsId);
        }
        return PEprice+drugsPrice+opPrice;
    }

//设置处方表对象
    public Prescription getPrescroption(int pId, Double totalPrice,String preName,StringBuffer preRemarks,String doctorWord,StringBuffer t_id){
        //创建处方对象,设置对象属性,执行插入，返回插入的处方数据的id
        Prescription prescription = new Prescription();
        prescription.setPreOpenDate(new Date());    //开方时间
        prescription.setpId(pId);                   //当前患者id
        prescription.setuDoctorName("未获取登陆的医生，假数据"); //未完成登陆页面，先写假数据
        prescription.setPreMoney(totalPrice);     //处方总价
        prescription.setPreName(preName+"的处方");     //处方名字
        prescription.setPreRemarks(preRemarks.toString());                 //给药房的备注
        prescription.setDoctorWord(doctorWord);
        prescription.setT_id(t_id.toString());
        return prescription;
    }

    //清空所有全局参数
    private boolean emptyParam(){
        boolean check = true;
        try {
            PEList.clear();
            DTList.clear();
            oplist.clear();
            CTMList.clear();
            WmList.clear();
            potcmList.clear();
            pch1 = null;

        }catch (Exception e){
            e.printStackTrace();
            check = false;
        }
        return check;
    }

    //根据id获取病例模板数据
    @RequestMapping("/getTemplateByid")
    public Map getTemplatebyId(Integer id){
        Map<String,Object> map = new HashMap<>();
        try {
            Template template = therapyService.getTemplateByid(id);
            if (template!=null){
                map.put("success",true);
                map.put("data",template);
            }else {
                map.put("success",false);
            }
        }catch (Exception e){
            e.printStackTrace();
            map.put("success",false);
        }
        return map;
    }

    //根据id获取院内协定方的药品等相关数据
    @RequestMapping("/getAgreementPartyTemplateById")
    public Map getAgreementPartyTemplateById(Integer id){
        Map<String,Object> map = new HashMap<>();

        try {
            Template template = therapyService.getAgreementPartyTemplateById(id);
            if (template!=null){
                map.put("success",true);
                map.put("data",template);
            }else {
                map.put("success",false);
            }
        }catch (Exception e){
            e.printStackTrace();
            map.put("success",false);
        }
        return map;
    }

    //根据id获取调理方数据
    @RequestMapping("/getOrganize")
    public Map getOrganize(Integer id){
        Map<String,Object> map = new HashMap<>();

        try {
        Template template = therapyService.getOrganize(id);
            if(template!= null){
                map.put("success",true);
                map.put("data",template);
            }else{
                map.put("success",false);
            }
        }catch (Exception e){
            e.printStackTrace();
            map.put("success",false);
        }
        return map;
    }

    //根据id查询患者病例
    @RequestMapping("/selectOldCase")
    public Map selectOldCase(Integer id){
        Map<String,Object> map = new HashMap<>();
        try {
            List<Patient_case_history> list=therapyService.selectOldCase(id);
            if (list.size()!=0){
                map.put("success",true);
                map.put("data",list);
            }else{
                map.put("success",false);
                map.put("message","没有该患者历史病例");
            }
        }catch (Exception e){
            e.printStackTrace();
            map.put("success",false);
        }
        return map;
    };



    //测试
    @RequestMapping(value = "/testController",method = {RequestMethod.POST})
    public Map testController(@RequestBody(required = false) List<Template> arrayData){
        Map<String,Object> map = new HashMap<>();
        if (arrayData!=null){
            map.put("success",true);
            for (Template t:arrayData){
                System.out.println(t.getDr_name());  //药品名
                System.out.println(t.getDr_ids());  //药品id字符串
                System.out.println(t.getId());      //模板id
            }
        }else {
            map.put("success",false);
            System.out.println("没接收到数组");
        }
        return map;
    }


}
